import {
  MiddlewareConsumer,
  Module,
  NestModule,
  ValidationError,
  ValidationPipe,
} from '@nestjs/common';
import { PrismaService } from 'prisma/prisma.server';
import { AdminModule } from 'src/admin/admin.module';
import { CommonModule } from './common/conmon.module';
import { HouseModule } from 'src/house/house.module';
import { Config } from './config';
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
import { ThrottlerStorageRedisService } from 'nestjs-throttler-storage-redis';
import { APP_FILTER, APP_GUARD, APP_PIPE } from '@nestjs/core';
import { ValidationException } from './exception/ValidationException';
import {
  AuthorizationFilter,
  BadRequestFilter,
  GlobalErrorFilter,
  MulterErrFilter,
  NotFoundErrFilter,
  ThrottlerExceptionFilter,
} from './filter/interface.filter';
import { AuthMiddleware } from './middleware/auth/auth.middleware';
import { AuthService } from './Auth/auth.service';
import { JwtModule, JwtService } from '@nestjs/jwt';
import { ShellModule } from './shell/shell.module';
import { Logger } from './utils/logger.server';
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';

@Module({
  imports: [
    AdminModule,
    CommonModule,
    ShellModule,
    HouseModule,
    ThrottlerModule.forRoot({
      throttlers: [
        {
          name: 'default',
          ttl: Config.rateLimit.ttl,
          limit: Config.rateLimit.limit,
        },
      ],
      storage:
        Config.rateLimit.storage === 'redis'
          ? new ThrottlerStorageRedisService({
              ...Config.redis,
              disconnectTimeout: 60 * 5 * 1000,
            })
          : null,
    }),
    JwtModule.register({
      secret: Config.token.secret,
      signOptions: { expiresIn: Config.token.expiresIn },
    }),
    ServeStaticModule.forRoot({
      rootPath: join(__dirname, '..', 'files'), // 指定静态文件目录
      serveRoot: '/files', // 指定请求路径前缀
    }),
  ],
  controllers: [],
  providers: [
    {
      provide: APP_GUARD,
      useClass: ThrottlerGuard,
    },

    {
      provide: APP_FILTER,
      useClass: GlobalErrorFilter,
    },

    {
      provide: APP_FILTER,
      useClass: NotFoundErrFilter,
    },
    {
      provide: APP_FILTER,
      useClass: BadRequestFilter,
    },
    {
      provide: APP_FILTER,
      useClass: AuthorizationFilter,
    },
    {
      provide: APP_FILTER,
      useClass: ThrottlerExceptionFilter,
    },
    {
      provide: APP_FILTER,
      useClass: MulterErrFilter,
    },
    {
      provide: APP_PIPE,
      useFactory() {
        return new ValidationPipe({
          whitelist: true, // 自动剔除非 DTO 类中的字段
          // forbidNonWhitelisted: true, // 如果存在非 DTO 类中的字段则抛出异常
          exceptionFactory: (errors: ValidationError[]) => {
            const messages = errors
              .map((error) => Object.values(error.constraints))
              .flat();
            return new ValidationException(`参数验证失败: ${messages[0]}`);
            // return new ValidationException(`参数验证失败: ${messages.join(', ')}`);
          },
        });
      },
    },
    PrismaService,
    JwtService,
    AuthService,
    Logger,
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(AuthMiddleware)
      .exclude('/admin/login', '/admin/logout', '/captcha')
      .forRoutes('*');
  }
}
